using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using Unity.Plastic.Newtonsoft.Json;
using Unity.VisualScripting;
using UnityEditor;
using UnityEngine;
using UnityEngine.UIElements;

public class AutoBindComponent : EditorWindow
{
    [SerializeField]
    private VisualTreeAsset m_VisualTreeAsset = default;

    //[SerializeField]
    //private Toggle autoOn = default;

    readonly List<string> fruits = new()
    {
        "Banana",
        "Apple",
        "Lime",
        "Orange"
    };

    [MenuItem("Window/UI Toolkit/AutoBindComponent")]
    public static void ShowExample()
    {
        AutoBindComponent wnd = GetWindow<AutoBindComponent>();
        wnd.titleContent = new GUIContent("AutoBindComponent");
    }

    ListView mListView;


    private List<GameObject> waitBindObjList = new List<GameObject>();

    public void CreateGUI()
    {
        // Each editor window contains a root VisualElement object
        VisualElement root = rootVisualElement;

        // VisualElements objects can contain other VisualElement following a tree hierarchy.
        VisualElement label = new Label("First plugin");

        //new Toggle
        root.Add(label);

        // Instantiate UXML
        VisualElement labelFromUXML = m_VisualTreeAsset.Instantiate();
        root.Add(labelFromUXML);

        SetupButtonHandler();
    }

    private void OnSelection(Selection s)
    {

    }

    private void OnValidateCommand(ValidateCommandEvent evt)
    {
        if (evt.commandName == "Copy" && mListView.selectedIndices.Count() > 0)
        {
            evt.StopPropagation();
        }
        else
        {
            evt.StopPropagation();
        }
    }

    private void OnExecuteCommand(ExecuteCommandEvent evt)
    {
        if (evt.commandName == "SelectAll")
        {
            Debug.Log("selectAll" + evt.target);
        }
        if (evt.commandName == "Copy" && mListView.selectedIndices.Count() > 0)
        {
            // mListView知道当前选中的是哪一个元素
            EditorGUIUtility.systemCopyBuffer = fruits[mListView.selectedIndex];
            evt.StopPropagation();
        }
        else if (evt.commandName == "Paste" && !string.IsNullOrEmpty(EditorGUIUtility.systemCopyBuffer))
        {
            fruits.Add(EditorGUIUtility.systemCopyBuffer);
            mListView.RefreshItems();
            evt.StopPropagation();
        }
    }


    private void OnBoolChangeEvent(ChangeEvent<bool> evt)
    {
        Debug.Log("type is " + evt.target.GetType());
        Debug.Log("target is " + evt.target.ToString());

        //evt.target
        Debug.Log("currentTarget is " + evt.currentTarget.ToString());

        Debug.Log("new Value is " + evt.newValue);
    }

    private void SetupButtonHandler()
    {
        VisualElement root = rootVisualElement;
        var buttons = root.Query<Button>();

        buttons.ForEach(RegisterHandler);
    }

    private void RegisterHandler(Button button)
    {
        UIType data = UIType.BOOLEAN;
        Debug.Log("button's name is " + button.viewDataKey);
        switch (button.viewDataKey)
        {
            case "autoBind":
                button.RegisterCallback<ClickEvent, UIType>(BindToyComp, data);
                break;
            case "getNames":
                button.RegisterCallback<ClickEvent>(ExtractNames);
                break;
        }
        // button.style.backgroundColor = new Color(UnityEngine.Random.Range(0,1f),UnityEngine.Random.Range(0,1f), UnityEngine.Random.Range(0,1f));

    }

    private void ExtractNames(ClickEvent evt)
    {

        List<string> names = new List<string>();
        Dictionary<string, List<string>> namesMap = new Dictionary<string, List<string>>();
        Dictionary<string, List<float>> posMap = new Dictionary<string, List<float>>();

        List<string> strings = new List<string>();
        namesMap.Add("levels", strings);

        if (waitBindObjList.Count > 0)
        {

            foreach (GameObject item in waitBindObjList)
            {
                strings.Add(item.name);
                // names.Add(item.name);
                List<float> floats = new List<float>();
                floats.Add(item.transform.eulerAngles.x);
                floats.Add(item.transform.eulerAngles.y);
                floats.Add(item.transform.eulerAngles.z);

                posMap.Add(item.name, floats);
            }
            string json = JsonConvert.SerializeObject(namesMap, Formatting.Indented);
            Debug.Log(json);
            string posMapStr = JsonConvert.SerializeObject(posMap, Formatting.Indented);

            string path = Path.Combine(Application.streamingAssetsPath, "config/allToy.json");
            string posMapPath = Path.Combine(Application.streamingAssetsPath, "config/posMap.json");
            File.WriteAllText(path, json);
            File.WriteAllText(posMapPath, posMapStr);

            AssetDatabase.SaveAssets();
            AssetDatabase.Refresh();
        }
    }

    private void BindToyComp(ClickEvent evt, UIType data)
    {
        VisualElement root = rootVisualElement;
        //evt.currentTarget
        // 绑定
        Debug.Log("Bind...,list length is " + waitBindObjList.Count + "  " + evt.target);

        if (waitBindObjList.Count > 0)
        {
            foreach (GameObject item in waitBindObjList)
            {
                AddToyComponentToObj(item);
            }
        }
    }

    /// <summary>
    /// 当前在编辑器中选择了一个节点或者是文件
    /// </summary>
    public void OnSelectionChange()
    {
        //Selection.gameObjects
        /*Transform[] trans = Selection.GetTransforms(SelectionMode.DeepAssets);
       
        Debug.Log("trans is " + trans.Length);

        for(int i = 0; i < trans.Length; i++)
        {
            Transform item = trans[i];
            Debug.Log("item's name is " + item.name);
        }*/

        GameObject[] objs = Selection.gameObjects;
        for (int i = 0; i < objs.Length; i++)
        {
            string pathItem = AssetDatabase.GetAssetPath(objs[i]);
            if (pathItem.IndexOf(".prefab") >= 0)
            {
                GameObject prefab = AssetDatabase.LoadAssetAtPath<GameObject>(pathItem);
                if (prefab != null)
                {
                    if (!waitBindObjList.Contains(prefab))
                    {
                        waitBindObjList.Add(prefab);
                    }

                }
                else
                {
                    Debug.Log("Failed to load prefab" + pathItem);
                }
            }
        }

        UnityEngine.Object selectObject = Selection.activeObject;

        Debug.Log("selectObject is " + selectObject);

        string path = AssetDatabase.GetAssetPath(selectObject);

        Debug.Log("path is " + path);

        // 文件夹中的选择会走这部分逻辑
        UnityEngine.Object[] allFile = Selection.objects;

        foreach (var item in allFile)
        {

        }
        Debug.Log("waitBindObjList's length is " + waitBindObjList.Count);

    }

    private void AddToyComponentToObj(GameObject prefab)
    {
        SetLayerResObj(prefab, 8);
        // Vector3 originScale = prefab.transform.localScale;
        // prefab.transform.localScale = new Vector3(originScale.x * 0.8f, originScale.y * 0.8f, originScale.z * 0.8f);

        if (prefab.GetComponent<Toy>() == null)
        {
            prefab.AddComponent<Toy>();
            // Vector3 originScale = prefab.transform.localScale;
            // prefab.transform.localScale = new Vector3(originScale.x * 60f, originScale.y * 60f, originScale.z * 60f);
        }

        
        EditorUtility.SetDirty(prefab);
        AssetDatabase.SaveAssets();
        AssetDatabase.Refresh();
        Mesh mesh = prefab.GetComponent<MeshFilter>().mesh;
        
        // if(prefab.GetComponent<MeshFilter>().mesh)
        if (prefab.GetComponent<MeshCollider>() != null)
        {
            Debug.Log("刷新完编辑器之后才有MeshCollider");
            prefab.GetComponent<MeshCollider>().convex = true;
        }
        if (prefab.GetComponent<Outline>() != null)
        {
            Outline outline = prefab.GetComponent<Outline>();
            outline.OutlineColor = new Color(1f, 229f / 255f, 0f, 1f);
            outline.enabled = false;
        }
    }

    private void SetLayerResObj(GameObject obj, int layer)
    {
        obj.layer = layer;
        foreach (Transform child in obj.transform)
        {
            SetLayerResObj(child.gameObject, layer);
        }
    }

    private void OnHierarchyChange()
    {
        // 编辑器中Hierarchy面板发生变化

    }

    private void OnLostFocus()
    {
        // 失去焦点
    }

    private void OnFocus()
    {
        // 获取到焦点
    }

    private void Update()
    {

    }

    private void OnDestroy()
    {

    }
}

public class CustomLabel : Label
{
    private static int m_InstanceCounter = 0;
    private int mLabelNumber;

    public CustomLabel() : base()
    {
        mLabelNumber = ++m_InstanceCounter;
        text = $"Label #{mLabelNumber} - click me to detach";
        RegisterCallback<AttachToPanelEvent>(evt =>
        {
            Debug.Log($"I'm label {mLabelNumber} and i " + $"Just got attach to panel {evt.destinationPanel.visualTree.name}");
        });
        RegisterCallback<DetachFromPanelEvent>(evt =>
        {
            Debug.Log($"panel is {evt.originPanel.visualTree.name}");
        });
        RegisterCallback<PointerDownEvent>(evt => this.RemoveFromHierarchy());
    }
}
